#!/bin/bash
controllerList=()
checkStatus=0

StorcliSupportList='SAS2208,SAS3108'


function getStrValue(){
	grepKey=$1
	grepFile=$2
	grep "${grepKey}" $grepFile |head -n 1| awk -F":" '{print $2}' | awk '{gsub(/^\s+|\s+$/, "");print}'

}

function isExist(){

	sn=$1
	checkStatus=0

	for ((i=0; i<${#controllerList[*]} ; i++))
	do
		if [ "${controllerList[i]}" == "$sn" ];then
			checkStatus=1
			return 
		fi
	done

	controllerList[${#controllerList[*]}]=$sn
	return 
}

function getHPssaPd(){
	slot=$1
	OLD_IFS=$IFS
	IFS=$'\n'

	pdinfo_file="hpssacli.pd.log"

	for pdid in `hpssacli controller slot=${slot} physicaldrive all show |grep physicaldrive |awk '{print $2}'`;
	do

		hpssacli controller slot=${slot} physicaldrive ${pdid} show >$pdinfo_file
		pd_model=`getStrValue  "Model" $pdinfo_file`
		pd_size=`getStrValue  "Size" $pdinfo_file`
		pd_drive=`getStrValue  "Drive Type" $pdinfo_file`
		pd_diskName=`getStrValue  "Disk Name" $pdinfo_file`

		echo "model=${pd_model};size=${pd_size};drive=${pd_drive};diskname=${pd_diskName}"
	done

}

function logSplitToFile(){
	logfile=$1
	splitStr=$2
	diskLogPath=$3
	diskInfoFile=""
	startSplit=0
	i=0
	if [ ! -d "$diskLogPath" ];then
		mkdir -p $diskLogPath
	fi

	rm ${diskLogPath}/* -f 
	while read line
	do
		if [[ "$line" == "$splitStr" ]];then
			let i++
			diskInfoFile="${diskLogPath}/${i}.log"
			startSplit=1
		fi

		if [ $startSplit -eq 1 ];then
			echo "$line" >>$diskInfoFile
		fi

		if [[ "$line" == "" ]];then
			startSplit=0
		fi

	done < $logfile

}

## 从导出的raid器信息中读取物理硬盘的情况
## Sas3ircu
function getSas3ircuDevice(){

	controllerId=$1
	deviceInfoPath=$2
	for diskId in `ls ${deviceInfoPath}`;
	do
		diskInfoFile="${deviceInfoPath}/${diskId}"

		diskSlot=`getStrValue  "Slot #" $diskInfoFile`
		diskSn=`getStrValue  "Serial No" $diskInfoFile`
		diskModel=`getStrValue  "Product Id" $diskInfoFile`
		diskBrand=`getStrValue  "Vendor Id" $diskInfoFile`
		diskSize=`getStrValue  "Capacity" $diskInfoFile`

		if [ -z "$diskSn" ] || [ -z "$diskModel" ];then
			continue
		fi
        echo "category=disk;brand=${diskBrand};model=${diskModel};sn=${diskSn};size=${diskSize};health=;lable=;slot=${diskSlot};raidcontroller=${controllerId}"
	done
}

## 从导出的raid器信息中读取物理硬盘的情况
## Sas3ircu
function getSas3ircuDevice(){

	controllerId=$1
	deviceInfoPath=$2
	for diskId in `ls ${deviceInfoPath}`;
	do
		diskInfoFile="${deviceInfoPath}/${diskId}"

		diskSlot=`getStrValue  "Slot #" $diskInfoFile`
		diskSn=`getStrValue  "Serial No" $diskInfoFile`
		diskModel=`getStrValue  "Model Number" $diskInfoFile`
		diskBrand=`getStrValue  "Manufacturer" $diskInfoFile`
		diskSize=`getStrValue  "Size " $diskInfoFile`

		if [ -z "$diskSn" ] || [ -z "$diskModel" ];then
			continue
		fi
        echo "category=disk;brand=${diskBrand};model=${diskModel};sn=${diskSn};size=${diskSize};health=;lable=;slot=${diskSlot};raidcontroller=${controllerId}"
	done
}
function getHPssaCli(){
	OLD_IFS=$IFS
	IFS=$'\n'
	ctl_info_file="/tmp/hpssacli-all.log"
	hpssacli controller all show pdctrlinfo > $ctl_info_file  2>/dev/null
	if [ $? -ne 0 ];then
		## not hpssa controller
		return 
	fi

	for txt in `cat $ctl_info_file |egrep -v '^$'`;
	do

		raidModel=`echo $txt | awk -F' in ' '{print $1}'`
		raidSn=`echo $txt | awk -F":" '{print $2}'| awk '$1=$1'`
		slot=`echo $txt | awk -F' Slot ' '{print $2}' |awk '{print $1}'`

		#echo "category=${category};model=$raidModel;sn=$raidSn;slot=$slot"
		echo "category=${category};brand=${brand};model=${raidModel};sn=${raidSn};slot=${slot};version=${version};cache=${cache};controller=${controller}"


		if [ "$getPD"  -eq 1 ];then
			getHPssaPd $slot
		fi
	done
}

## 通过Sas3ircu /通过Sas2ircu 来读取raid卡信息及硬盘情况
## 适用于浪潮 3008类的卡
## 参数1  sasircu的版本 支持2/3二个值
function getSasircu(){

	ctl_version=$1

	ctl_info_file="sas${ctl_version}ircu.log"

	for i in {0..9};
	do
	## 
	    ctl_info_file="/tmp/sas${ctl_version}ircu-${i}.log"
	    sas${ctl_version}ircu ${i} display > $ctl_info_file 2>/dev/null
		if [ $? -eq 0 ];then
			raidModel=`getStrValue  "Controller type" $ctl_info_file`
			raidControllerId=$i
			slot=`lspci -nn |grep ${vendorid}:${deviceid} |awk '{print $1}'`


			#echo "category=${category};model=${raidModel};sn=;slot=${raidControllerId}"
			echo "category=${category};brand=${brand};model=${raidModel};sn=${raid_sn};slot=${slot};version=${version};cache=${cache};controller=${controller}"

			deviceTmpPath="/tmp/raidcontroller/sas${ctl_version}ircu/${raidControllerId}/"

			if [ "$getPD"  -eq 1 ];then
				##拆份日志
				logSplitToFile $ctl_info_file "Device is a Hard disk" $deviceTmpPath
				getSas3ircuDevice $raidControllerId $deviceTmpPath
			fi
		fi
	done

}

function getMegaCli64(){

	ctl_info_file="/tmp/megacli.log"
	deviceTmpPath="/tmp/raidcontroller/megacli/"



	##1. get all raid Adapter
	/opt/MegaRAID/MegaCli/MegaCli64 -AdpAllInfo -aALL >$ctl_info_file 2> /dev/null
	if [ $? -ne 0 ];then
		##服务器读不到megacli支持的卡
		return
	fi


	raidModel=`getStrValue  "Product Name" $ctl_info_file`
	if [ -z "$raidModel" ];then
		## 无法识别到sn或raid型号则不输出
		return 
	fi

	#echo $StorcliSupportList |grep $raidModel > /dev/null
	#if [ $? -eq 0 ];then
		## 它是Storcli支持的卡
	#	return 
	#fi

	raid_sn=`getRaidControllerSnMegaCli64 $ctl_info_file`
	if [ "$raid_sn" == "" ];then
		## 无法读到sn 跳过
		return 
	fi

	isExist $raid_sn
	if [ $checkStatus -eq 1 ];then
		这个sn号的卡已经通过其它工具抓出来了，跳过;
		return 
	fi

	version=`getStrValue "FW Package Build" $ctl_info_file`
	cache=`getStrValue "Memory Size" $ctl_info_file`
	controller=`echo $raidModel | awk '{print $2}'`

	vendorid=`getStrValue "Vendor Id" $ctl_info_file`
	deviceid=`getStrValue "Device Id" $ctl_info_file`
	slot=`lspci -nn |grep ${vendorid}:${deviceid} |awk '{print $1}'`
	

	brand="LSI"

	echo "category=${category};brand=${brand};model=${raidModel};sn=${raid_sn};slot=${slot};version=${version};cache=${cache};controller=${controller}"

}

function getRaidControllerSnMegaCli64(){

	ctl_info_file=$1
	raid_sn=''
	i=3

	while [[ $raid_sn == '' ]]; do
		#statements
		raid_sn=`getStrValue  "Serial No" $ctl_info_file`

		if [ "$raid_sn" == '' ];then

			sleep 5

			/opt/MegaRAID/MegaCli/MegaCli64 -AdpAllInfo -aALL >$ctl_info_file 2> /dev/null

			i=`expr $i - 1`

			#超过i=3次还是抓不到就放弃
			if [ $i -lt 1 ];then
				break;
			fi
		fi
	done

	echo $raid_sn
	## sn
}

function getRaidControllerSnStorcli(){

	controllerId=$1
	ctl_info_file=$2
	raid_sn=''
	i=3

	while [[ $raid_sn == '' ]]; do
		#statements
		raid_sn=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.'"Serial Number"' |sed 's/"//g'`

		if [ "$raid_sn" == '' ];then

			sleep 5

			/opt/MegaRAID/storcli/storcli64 /c${controllerId} show all J >$ctl_info_file

			i=`expr $i - 1`

			#超过i=3次还是抓不到就放弃
			if [ $i -lt 1 ];then
				break;
			fi
		fi
	done

	echo $raid_sn
		## sn
		
}


function getStorcli(){
	for i in {0..3};
	do
		ctl_info_file="/tmp/storcli-${i}.json"
		/opt/MegaRAID/storcli/storcli64 /c${i} show all J >$ctl_info_file
		if [ $? -ne 0 ];then
			# 无法识别
			continue
		fi

		console_status=`cat $ctl_info_file | jq .Controllers[0].'"Command Status"'.Status |sed 's/"//g'`
		if [[ "$console_status" == "Success" ]];then

			
			raid_sn=`getRaidControllerSnStorcli $i $ctl_info_file`
			if [ "$raid_sn" == "" ];then
			## 无法读到sn 跳过
				return 
			fi
			
			isExist $raid_sn
			if [ $checkStatus -eq 1 ];then
				## 这个sn号的卡已经通过其它工具抓出来了，跳过;
				continue
			else
				echo -n "sn=${raid_sn};"
			fi

			## model
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.Model |sed 's/"//g'`
			echo -n "model=${consoleValue};"



			## slot
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.'"PCI Address"' |sed 's/"//g'`
			echo -n "slot=${consoleValue};"

			## Version
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Version.'"Firmware Package Build"' |sed 's/"//g'`
			echo -n "version=${consoleValue};"

			## cache
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.HwCfg.'"On Board Memory Size"' |sed 's/"//g'`
			echo -n "cache=${consoleValue};"

			## controller
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.Model |awk '{print $2}' |sed 's/"//g'`
			echo -n "controller=${consoleValue};"

			## controller
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.Model |awk '{print $1}' |sed 's/"//g'`
			echo -n "brand=${consoleValue};"

			## sadaddress
			consoleValue=`cat $ctl_info_file | jq .Controllers[0].'"Response Data"'.Basics.'"SAS Address"' |sed 's/"//g' | awk '$1=$1'`
			echo -n "sasaddress=${consoleValue};"

			##end 
			echo "category=${category}"
		fi
	done
}
category="raidcontroller"

## 是否从控制器中读取硬盘信息
## 0 不读
## 1 读
getPD=0
getHPssaCli
#getSasircu 2
#getSasircu 3
getMegaCli64
getStorcli